/*
 * select.c
 */
#include <system.h>
#include <v93.h>
#include <libm.h>
#include <nt.h>
#include "spec.h"
#include "vardecl.h"
#include "adp.h"
#include "adpcm.h"
#include "psgdef.h"

#ifndef LOCAL
#define LOCAL
#endif

/* 
----------------------------------------
  ローカル変数
----------------------------------------
*/
#define PLAYER_POS_X  40
#define PLAYER_POS_Y  10
#define FIELD_POS_X   8
#define FIELD_POS_Y   128
#define P2_OFFSET     128

LOCAL unsigned short StarBuffer[6];
LOCAL int p1sel, p2sel;                /* 選択済みフラグ */
LOCAL unsigned short FacetColor[PLAYER_MAX];

/* 
----------------------------------------
  ローカル関数
----------------------------------------
*/
LOCAL void DispParam( int UnitNumber, int X_pos);
LOCAL void MakeStars( int number );
LOCAL void NameAndStars(int p1type, int p2type);

LOCAL unsigned char *MenuItem[] = {
  "Nam",
  "Acc",
  "Brk",
  "Hnd",
  "Wgt",
};

/*
----------------------------------------
  機体イメージパラメータの表示
  画面モードは１でサイズがノーマルであることが前提
  引き数：int p1type,int p2type
    p1type : 左側に表示するマシンのタイプ
    p2type : 右側に表示するマシンのタイプ
  戻り値：なし
----------------------------------------
 */
LOCAL void
MakeSelect(int p1type, int p2type)
{
  int i;

  KINGKanjiMode(PSET, YUV_BLACK); /* 黒色で書く */
  /* 共通部分表示 */
  for (i = 0; i < 5; i++) {
    KINGPuts(FIELD_POS_X, FIELD_POS_Y + 18 * i, MenuItem[i]);
    KINGPuts(FIELD_POS_X + P2_OFFSET, FIELD_POS_Y + 18 * i, MenuItem[i]);
  }
  /* パラメータを表示する */
  NameAndStars(p1type, PLAYER1);
  NameAndStars(p2type, PLAYER2);
}

/* 
----------------------------------------
  機体名とパラメータを星で表す
  引き数：int playertype, int which
    playertype : マシンのタイプ
    which      : 左か右か
  戻り値：なし
----------------------------------------
*/
LOCAL void
NameAndStars(int playertype, int which)
{
  int offset;
  
  offset = 0;
  if (which == PLAYER2)
    offset = P2_OFFSET;
  VSyncWait();
  KINGPutRect(FIELD_POS_X + 32 + offset,FIELD_POS_Y,
    FIELD_POS_X+32+80+offset, FIELD_POS_Y + 90,
    filereadbuf + ((offset == 0) ? 0 : 14400));
  /* 名前と★を書く */
  DispParam(playertype, FIELD_POS_X + 32 + offset);
}

/*
----------------------------------------
  名前と★マークを表示する。
  AccelLevel等が配列になっていれば for文で書ける
  引き数：int UnitNumber, int X_pos
    UnitNumber : マシンのタイプ
    X_Pos      : 表示しはじめるＸ座標
  戻り値：なし
----------------------------------------
 */
LOCAL void
DispParam(int UnitNumber, int X_pos)
{
  KINGKanjiMode(PSET, YUV_WHITE); /* 色を緑色にする */
  /* 機種名の表示 */
  KINGPuts(X_pos, FIELD_POS_Y,
    MachineImage[UnitNumber].MachineName);

  KINGKanjiMode(PSET, YUV_YELLOW); /* 色を黄色にする */
  /* アクセルレベル表示 */
  MakeStars(MachineImage[UnitNumber].AccelLevel);
  KINGPuts(X_pos, FIELD_POS_Y + 18    , (char *)StarBuffer);

  /* ブレーキレベル表示 */
  MakeStars(MachineImage[UnitNumber].BrakeLevel);
  KINGPuts(X_pos, FIELD_POS_Y + 18 * 2, (char *)StarBuffer);
    
  /* ハンドリング表示 */
  MakeStars(MachineImage[UnitNumber].Handling);
  KINGPuts(X_pos, FIELD_POS_Y + 18 * 3, (char *)StarBuffer);

  /* 重さ表示 */
  MakeStars(MachineImage[UnitNumber].Weight);
  KINGPuts(X_pos, FIELD_POS_Y + 18 * 4, (char *)StarBuffer);
}

/*
----------------------------------------
  渡された個数から、★マークのならんだ文字列を作る
  引き数：int number
    number : ★の数
  戻り値：なし
----------------------------------------
 */
LOCAL void
MakeStars(int number)
{
  int i;

  StarBuffer[0] = 0;
  if(number > 5) number = 5;
  for( i = 0; i < number; i++){
    StarBuffer[ i ] = 0x9a81; /* ★ */
  }
  StarBuffer[ i ] = 0;
}

/*
----------------------------------------
  機体を選択用に表示する
  引き数：なし
  戻り値：なし
----------------------------------------
*/
LOCAL void
DrawTwoCar(void)
{
  static int rot1 = 0;
  static int rot2 = 0;
  int which;

  /* 視点の設定 */
  AGLResetCamera();
  AGLTranslateCamera(0, -0x10, 0x06);
  AGLRotateCameraX(750);
  AGLPerspectiveCamera(0xffc0 * SCALE_PERS);
  AGLZoomCamera(CAM_ZOOM, CAM_ZOOM, 0x20);
  
  /* 車のマトリクス計算 */
  for (which = PLAYER1; which < PLAYER_MAX; which++) {
    register machine *mp;
    
    mp = &Machine[which];
    AGLResetObj(&mp->type->obj); /* オブジェクトマトリクス初期化 */
    /* デフォルトカラー設定 */
    FarlSetDefColorReg((mp->type->color & 0xff00) + FacetColor[which]);
    /* スケール決定 */
    AGLScaleObj(&mp->type->obj, SCALE_CAR / 8, SCALE_CAR / 8, SCALE_CAR / 8);
    /* 向き決定 */
    AGLRotateObjX(&mp->type->obj, 900);
    /* フラグがFALSEになっていたら回転しない */
    AGLRotateObjZ(&mp->type->obj,
      (which == PLAYER1) 
      ? ((p1sel == FALSE) ? rot1 : (rot1 = 0))
      : ((p2sel == FALSE) ? rot2 : (rot2 = 0)));
    /* 位置決定 */
    AGLTranslateObj(&mp->type->obj,
                    FarlFix187(Locate[which][LX]),
                    FarlFix187(Locate[which][LY]),
                    FarlFix187(Locate[which][LZ])
                    );
    /* 描画 */
    AGLFixPutObj(&Machine[which].type->obj);
  }
  ASLSync(); AGLShot(); MSLSync();
  /* 回転角度増加 */
  rot1 += 100;
  rot1 %= 3600;
  rot2 += 100;
  rot2 %= 3600;
}

/* 
========================================
  機種選択用の車体表示
  引き数：なし
  戻り値：なし
========================================
*/
enum {
  ORDER1,
  ORDER2,
  ORDER3,
  ORDER_MAX,
};

typedef struct {
  unsigned short *obj;
  long len;
  float width;
  float h_plus;
  float h_minus;
  int color;
} machOrder;
LOCAL machOrder selorder[ORDER_MAX]; /* 3機の中から選べる */

void
SelectCar(void)
{
  int i;
  /* ちょうど良い大きさに縮める */
  float scale = FarlFloat187(SCALE_CAR) * OBJ_SCALE / 0.8;

  InitPlayer();
  machPlayer1 = ORDER1;
  machPlayer2 = ORDER2;
  p1sel = p2sel = FALSE;

  /* ＰＳＧの曲をストップ */
  PSGClear();
  /* セレクト画面用の曲をならす */
  PSGPlay(MU_SELECT);
  /* C6272 の初期化 */
  KINGScreen(1);
  KINGChangeSize0(DISP_NORMAL);
  KINGCls(KING_BG0);  /* 画面クリア */
  KINGDispOff();
  KINGTrans(KING_BG0, pict_bg4_fxg,1);
  KINGDispOn();

  /* 文字表示部分の背景保存 */
  KINGGetRect(FIELD_POS_X + 32 ,FIELD_POS_Y,
    FIELD_POS_X + 32 + 80, FIELD_POS_Y + 90,filereadbuf);

  KINGGetRect(FIELD_POS_X + 32 + P2_OFFSET, FIELD_POS_Y,
    FIELD_POS_X + 32 + 80 + P2_OFFSET, FIELD_POS_Y + 90,filereadbuf + 14400);
  /* 選択機種オブジェクトデータ設定 */
  /* 
   * obj*_minmax[] はオブジェクトの最少座標、最大座標が格納されている
   */

  selorder[ORDER1].obj    = obj05_g;
  selorder[ORDER1].len    = obj05_g_length / sizeof(int);
  selorder[ORDER1].width  = FarlFloat1015(obj05_minmax[MAXX]) / scale;
  selorder[ORDER1].h_plus = FarlFloat1015(obj05_minmax[MAXZ]) / scale;
  selorder[ORDER1].h_minus= FarlFloat1015(obj05_minmax[MINZ]) / scale;
  selorder[ORDER1].color  = CarColor[ORDER1];

  selorder[ORDER2].obj    = obj03_g;
  selorder[ORDER2].len    = obj03_g_length / sizeof(int);
  selorder[ORDER2].width  = FarlFloat1015(obj03_minmax[MAXX]) / scale;
  selorder[ORDER2].h_plus = FarlFloat1015(obj03_minmax[MAXZ]) / scale;
  selorder[ORDER2].h_minus= FarlFloat1015(obj03_minmax[MINZ]) / scale;
  selorder[ORDER2].color  = CarColor[ORDER2];

  selorder[ORDER3].obj    = obj04_g;
  selorder[ORDER3].len    = obj04_g_length / sizeof(int);
  selorder[ORDER3].width  = FarlFloat1015(obj04_minmax[MAXX]) / scale;
  selorder[ORDER3].h_plus = FarlFloat1015(obj04_minmax[MAXZ]) / scale;
  selorder[ORDER3].h_minus= FarlFloat1015(obj04_minmax[MINZ]) / scale;
  selorder[ORDER3].color  = CarColor[ORDER3];

  /* 1P メニュー初期位置の決定 */
  Locate[PLAYER1][LX] = -0.08;
  Locate[PLAYER1][LY] = 0.0;
  Locate[PLAYER1][LZ] = 0.06;
  Machine[PLAYER1].direct = 0;
  Machine[PLAYER1].type->obj.geometryTop = (int *)selorder[machPlayer1].obj;
  Machine[PLAYER1].type->obj.geometryLength = selorder[machPlayer1].len;
  Machine[PLAYER1].type->obj.material = &aMaterial[machPlayer1];
  Machine[PLAYER1].type->color = selorder[machPlayer1].color;

  Machine[PLAYER1].type->width = selorder[machPlayer1].width;
  Machine[PLAYER1].type->h_plus = selorder[machPlayer1].h_plus;
  Machine[PLAYER1].type->h_minus = selorder[machPlayer1].h_minus;
  /* 2P メニュー初期位置の決定 */
  Locate[PLAYER2][LX] = 0.08;
  Locate[PLAYER2][LY] = 0.0;
  Locate[PLAYER2][LZ] = 0.06;
  Machine[PLAYER2].direct = 0;
  Machine[PLAYER2].type->obj.geometryTop = (int *)selorder[machPlayer2].obj;
  Machine[PLAYER2].type->obj.geometryLength = selorder[machPlayer2].len;
  Machine[PLAYER2].type->obj.material = &aMaterial[machPlayer2];
  Machine[PLAYER2].type->color = selorder[machPlayer2].color;

  Machine[PLAYER2].type->width = selorder[machPlayer2].width;
  Machine[PLAYER2].type->h_plus = selorder[machPlayer2].h_plus;
  Machine[PLAYER2].type->h_minus = selorder[machPlayer2].h_minus;

  /* 念のために画面をスワップ */
  ASLSync();
  AGLShot();
  MSLSync();
  /* 最初の表示 */
  MakeSelect(machPlayer1, machPlayer2);
  NameAndStars(machPlayer1, PLAYER1);
  NameAndStars(machPlayer2, PLAYER2);
  FacetColor[PLAYER1] = CarColor[machPlayer1] & 0x0f;
  FacetColor[PLAYER2] = CarColor[machPlayer2] & 0x0f;
  DrawTwoCar();

  /* ライト初期化 */
  AGLResetLight(AGL_LIGHT0);
  AGLResetLight(AGL_LIGHT1);
  AGLSetLight(AGL_LIGHT0, 0, 0x1000, 0x7fff, 0x7000);
  AGLRotateLightY(AGL_LIGHT0, 700);
  AGLRotateLightZ(AGL_LIGHT0, 2700);

  dispon(bg | spr);

  /* パッド入力で選択 */
  while (1) {
    VSyncWait();
    get_pad();
    Pad00 = pad00;
    Pad10 = pad10;

    /* run が押されたときの処理 */
    if (!p1sel && ((Pad00.KD_TRG & KP_run) || (Pad00.KD_TRG & KP_1))) {
      PSGSeOn(SE_CURSEL);
      p1sel = TRUE;
    }
    if (!p2sel && ((Pad10.KD_TRG & KP_run) || (Pad10.KD_TRG & KP_1))) {
      PSGSeOn(SE_CURSEL);
      p2sel = TRUE;
    }
    if (p1sel && ((Pad00.KD_TRG & KP_2) || (Pad00.KD_TRG & KP_2))) {
      PSGSeOn(SE_CURSEL);
      p1sel = FALSE;
    }
    if (p2sel && ((Pad10.KD_TRG & KP_2) || (Pad10.KD_TRG & KP_2))) {
      PSGSeOn(SE_CURSEL);
      p2sel = FALSE;
    }
    /* プレイヤー1側上下で選択 */
    if (p1sel == FALSE) {
      if ((Pad00.KD_TRG & KP_up) || (Pad00.KD_TRG & KP_down)) {
        if (Pad00.KD_TRG & KP_up){
          machPlayer1--;
          if (machPlayer1 < 0)
            machPlayer1 = ORDER_MAX - 1;
        }
        else{
          machPlayer1++;
          if (machPlayer1 > ORDER_MAX - 1)
            machPlayer1 = ORDER1;
        }
        /* 車を変えてパラメータイメージの表示 */
        Machine[PLAYER1].type->obj.geometryTop
            = (int *)selorder[machPlayer1].obj;
        Machine[PLAYER1].type->obj.geometryLength
            = selorder[machPlayer1].len;
        Machine[PLAYER1].type->color = CarColor[machPlayer1];
        FacetColor[PLAYER1] = CarColor[machPlayer1] & 0x0f;
        NameAndStars(machPlayer1, PLAYER1);
        /* カーソル移動音をならす */
        PSGSeOn(SE_CURMOVE);
      }
      /* ３か４が押されたら色をかえる */
      if (Pad00.KD_TRG & KP_3){
        FacetColor[PLAYER1] = (FacetColor[PLAYER1] + 1) & 0x0f;
        if (FacetColor[PLAYER1] == 0) FacetColor[PLAYER1] = 1;
      }
      if (Pad00.KD_TRG & KP_4){
        FacetColor[PLAYER1] = (FacetColor[PLAYER1] - 1) & 0x0f;
        if (FacetColor[PLAYER1] == 0) FacetColor[PLAYER1] = 0x0f;
      }
    }

    /* プレイヤー2側上下で選択 */
    /* やってることは上と同じ */
    if (p2sel == FALSE) {
      if ((Pad10.KD_TRG & KP_up) || (Pad10.KD_TRG & KP_down)) {
        if (Pad10.KD_TRG & KP_up){
          machPlayer2--;
          if (machPlayer2 < 0)
            machPlayer2 = ORDER_MAX - 1;
        }
        else{
          machPlayer2++;
          if (machPlayer2 > ORDER_MAX - 1)
           machPlayer2 = ORDER1;
        }
        Machine[PLAYER2].type->obj.geometryTop
            = (int *)selorder[machPlayer2].obj;
        Machine[PLAYER2].type->obj.geometryLength
            = selorder[machPlayer2].len;
        Machine[PLAYER2].type->color = CarColor[machPlayer2];
        FacetColor[PLAYER2] = CarColor[machPlayer2] & 0x0f;
        NameAndStars(machPlayer2, PLAYER2);
        PSGSeOn(SE_CURMOVE);
      }
      if (Pad10.KD_TRG & KP_3){
        FacetColor[PLAYER2] = (FacetColor[PLAYER2] + 1) & 0x0f;
        if (FacetColor[PLAYER2] == 0) FacetColor[PLAYER2] = 1;
      }
      if (Pad10.KD_TRG & KP_4){
        FacetColor[PLAYER2] = (FacetColor[PLAYER2] - 1) & 0x0f;
        if (FacetColor[PLAYER2] == 0) FacetColor[PLAYER2] = 0x0f;
      }
    }
    /* 選択された車の回転表示 */
    DrawTwoCar();
    /* 両方とも決定されたらループから抜ける */
    if (p1sel && p2sel){
      dispoff(bg | spr);
      break;
    }
  }

  /* 1P object */
  Machine[PLAYER1].direct = 0;	/* 初めの向き */
  Machine[PLAYER1].type->obj.geometryTop = (int *)selorder[machPlayer1].obj;
  Machine[PLAYER1].type->obj.geometryLength = selorder[machPlayer1].len;
  Machine[PLAYER1].type->width = selorder[machPlayer1].width;
  Machine[PLAYER1].type->h_plus = selorder[machPlayer1].h_plus;
  Machine[PLAYER1].type->h_minus = selorder[machPlayer1].h_minus;
  Machine[PLAYER1].type->color =
    (CarColor[machPlayer1] & 0xff00) + FacetColor[PLAYER1];
  /* 2P object */
  Machine[PLAYER2].direct = 1800; /* 初めの向き */
  Machine[PLAYER2].type->obj.geometryTop = (int *)selorder[machPlayer2].obj;
  Machine[PLAYER2].type->obj.geometryLength = selorder[machPlayer2].len;
  Machine[PLAYER2].type->width = selorder[machPlayer2].width;
  Machine[PLAYER2].type->h_plus = selorder[machPlayer2].h_plus;
  Machine[PLAYER2].type->h_minus = selorder[machPlayer2].h_minus;
  Machine[PLAYER2].type->color =
    (CarColor[machPlayer2] & 0xff00) + FacetColor[PLAYER2];

  /* 1P ゲーム初期位置の決定 */
  Locate[PLAYER1][LX] = -5.0;
  Locate[PLAYER1][LY] = 0.0;
  Locate[PLAYER1][LZ] = 0.0;
  /* 2P ゲーム初期位置の決定 */
  Locate[PLAYER2][LX] = 5.0;
  Locate[PLAYER2][LY] = 0.0;
  Locate[PLAYER2][LZ] = 0.0;
}
